package org.skydiveapp;

import java.util.Date;

import org.skydiveapplibrary.data.Rig;
import org.skydiveapplibrary.data.RigComponent;
import org.skydiveapplibrary.data.RigReminder;
import org.skydiveapplibrary.repository.RigRepository;
import org.skydiveapplibrary.data.TimeUnit;
import org.skydiveapplibrary.data.RigReminder.DueStatus;
import org.skydiveapplibrary.ui.FormatUtility;
import org.skydiveapplibrary.ui.TableStyler;
import org.skydiveapplibrary.ui.TableStyler.TableRowLocation;
import org.skydiveapplibrary.util.RigReminderManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class RigEditActivity extends Activity
{
	// activity request codes
	private static final int REQUEST_NOTES = 0;
	private static final int REQUEST_COMPONENT = 1;
	private static final int REQUEST_REMINDER = 2;

	// repositories
	private RigRepository repository = new RigRepository(this);

	// menus
	private MenuItem saveMenu;
	private MenuItem cancelMenu;
	
	// data
	private boolean isEdit = false;
	private Rig rig;
	private RigComponent currentEditedComponent;
	private RigReminder currentEditedReminder;
	
	// listeners
	private OnClickListener notesEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			Intent intent = new Intent(RigEditActivity.this, NotesEditActivity.class);
			intent.putExtra(Constants.EXTRA_NOTES, rig.getNotes());
			startActivityForResult(intent, REQUEST_NOTES);
		}
	};
	private OnClickListener componentEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedComponent = (RigComponent)view.getTag();
			Intent intent = new Intent(RigEditActivity.this, RigComponentEditActivity.class);
			intent.putExtra(Constants.EXTRA_RIG_COMPONENT_IS_EDIT, true);
			intent.putExtra(Constants.EXTRA_RIG_COMPONENT_NAME, currentEditedComponent.getName());
			intent.putExtra(Constants.EXTRA_RIG_COMPONENT_SERIAL_NUMBER, currentEditedComponent.getSerialNumber());
			intent.putExtra(Constants.EXTRA_RIG_COMPONENT_NOTES, currentEditedComponent.getNotes());
			startActivityForResult(intent, REQUEST_COMPONENT);
		}
	};
	private OnClickListener addComponentListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedComponent = null;
			Intent intent = new Intent(RigEditActivity.this, RigComponentEditActivity.class);
			startActivityForResult(intent, REQUEST_COMPONENT);
		}
	};
	private OnClickListener reminderEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedReminder = (RigReminder)view.getTag();
			Intent intent = new Intent(RigEditActivity.this, RigReminderEditActivity.class);
			intent.putExtra(Constants.EXTRA_RIG_REMINDER_IS_EDIT, true);
			intent.putExtra(Constants.EXTRA_RIG_REMINDER_NAME, currentEditedReminder.getName());
			intent.putExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL, currentEditedReminder.getInterval());
			intent.putExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL_UNIT, currentEditedReminder.getIntervalUnit());
			intent.putExtra(Constants.EXTRA_RIG_REMINDER_LAST_COMPLETED_DATE, currentEditedReminder.getLastCompletedDate());
			startActivityForResult(intent, REQUEST_REMINDER);
		}
	};
	private OnClickListener addReminderListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedReminder = null;
			Intent intent = new Intent(RigEditActivity.this, RigReminderEditActivity.class);
			startActivityForResult(intent, REQUEST_REMINDER);
		}
	};
	private OnClickListener deleteListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			showDeleteWarning();
		}
	};
	private DialogInterface.OnClickListener deleteConfirmListener = new DialogInterface.OnClickListener()
	{
		@Override
		public void onClick(DialogInterface arg0, int arg1)
		{
			delete();
		}
	};
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		// load data
		loadData();
		
		// init ui
		initializeUI();
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent)
	{
		if (requestCode == REQUEST_NOTES && resultCode == RESULT_OK) 
		{
			String notes = intent.getStringExtra(Constants.EXTRA_NOTES);
			updateNotes(notes);
		}
		else if (requestCode == REQUEST_COMPONENT && resultCode == RESULT_OK)
		{
			boolean isDelete = intent.getBooleanExtra(Constants.EXTRA_RIG_COMPONENT_DELETE, false);
			String name = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_NAME);
			String serialNumber = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_SERIAL_NUMBER);
			String notes = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_NOTES);
			updateComponent(isDelete, name, serialNumber, notes);
		}
		else if (requestCode == REQUEST_REMINDER && resultCode == RESULT_OK)
		{
			boolean isDelete = intent.getBooleanExtra(Constants.EXTRA_RIG_REMINDER_DELETE, false);
			String name = intent.getStringExtra(Constants.EXTRA_RIG_REMINDER_NAME);
			int interval = intent.getIntExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL, 0);
			TimeUnit intervalUnit = (TimeUnit)intent.getSerializableExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL_UNIT);
			Date lastCompletedDate = (Date)intent.getSerializableExtra(Constants.EXTRA_RIG_REMINDER_LAST_COMPLETED_DATE);
			updateReminder(isDelete, name, interval, intervalUnit, lastCompletedDate);
		}
	}
	
	private void loadData()
	{
		// set isEdit flag
		Bundle extras = getIntent().getExtras();
		isEdit = (extras != null && extras.containsKey(Constants.EXTRA_RIG_ID));

		// determine add vs. edit
		if (isEdit)
		{
			// editing
			int id = getIntent().getExtras().getInt(Constants.EXTRA_RIG_ID);
			rig = repository.getRig(id);
		}
		else
		{
			// adding
			rig = new Rig();
		}
	}
	
	private void initializeUI()
	{
		// show view
		setContentView(R.layout.rig_edit_view);
		
		// set header text
		TextView headerTextView = (TextView)findViewById(R.id.EditHeaderTextView);
		headerTextView.setText(isEdit ?
				R.string.rig_edit_label : R.string.rig_new_label);

		// set name
		EditText nField = (EditText)findViewById(R.id.RigNameField);
		nField.setText(rig.getName());
		
		// set primary
		CheckBox pField = (CheckBox)findViewById(R.id.RigPrimaryField);
		pField.setChecked(rig.isPrimary());
		
		// set archived
		CheckBox aField = (CheckBox)findViewById(R.id.RigArchivedField);
		aField.setChecked(rig.isArchived());
		
		// set jump count
		TextView jcField = (TextView)findViewById(R.id.RigJumpCountField);
		jcField.setText(rig.getJumpCount() == 0 ? "0" :
			FormatUtility.toNumericString(rig.getJumpCount()));
		
		// set notes
		TextView notesField = (TextView)findViewById(R.id.RigNotesField);
		notesField.setText(rig.getNotes());
		notesField.setOnClickListener(notesEditListener);
		
		// init components UI
		initComponentsUI();
		
		// init reminders UI
		initRemindersUI();
		
		// add button listeners		
		Button deleteButton = (Button)findViewById(R.id.RigDeleteButton);
		deleteButton.setOnClickListener(deleteListener);
		
		// show/hide delete button
		deleteButton.setVisibility(isEdit ? View.VISIBLE : View.GONE);
	}
	
	private void initComponentsUI()
	{
		TableLayout tableLayout = (TableLayout)findViewById(R.id.RigComponentsTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getComponents().size(); i++)
		{
			// get component
			RigComponent component = rig.getComponents().get(i);
			
			// create row, add to table
			TableRow row = createComponentTableRow(component, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add component' row
		TableRow addRow = createAddTableRow(
				rig.getComponents().size() <= 0,
				R.string.rig_add_component_label,
				addComponentListener);
		tableLayout.addView(addRow);
	}
	
	private void initRemindersUI()
	{
		TableLayout tableLayout = (TableLayout)findViewById(R.id.RigRemindersTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getReminders().size(); i++)
		{
			// get reminder
			RigReminder reminder = rig.getReminders().get(i);
			
			// create row, add to table
			TableRow row = createReminderTableRow(reminder, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add reminder' row
		TableRow addRow = createAddTableRow(
				rig.getReminders().size() <= 0,
				R.string.rig_add_reminder_label,
				addReminderListener);
		tableLayout.addView(addRow);
	}
	
	private TableRow createComponentTableRow(RigComponent component, boolean first)
	{
		// create table row
		TableRow row = new TableRow(this);
		row.setTag(component);
		row.setOnClickListener(componentEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add component name
		TextView componentName = new TextView(this);
		componentName.setText(component.getName());
		// style
		TableStyler.styleTableRowTextView(this, componentName, false, false, true, 1);
		// add to row
		row.addView(componentName);
		
		return row;
	}
	
	private TableRow createReminderTableRow(RigReminder reminder, boolean first)
	{
		// create table row
		TableRow row = new TableRow(this);
		row.setTag(reminder);
		row.setOnClickListener(reminderEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add description
		TextView name = new TextView(this);
		name.setText(reminder.getName());
		// style
		TableStyler.styleTableRowTextView(this, name, false, false, false, 1);
		// add to row
		row.addView(name);
		
		// update fields based on due status
		Drawable icon = null;
		int textStyleId = R.style.FormFieldValueStyle;
		if (reminder.getDueStatus() == DueStatus.DueSoon)
		{
			textStyleId = R.style.DueSoonTextStyle;
		}
		else if (reminder.getDueStatus() == DueStatus.PastDue)
		{
			textStyleId = R.style.PastDueTextStyle;
			icon = getResources().getDrawable(R.drawable.skull_small);
		}
		name.setTextAppearance(this, textStyleId);
		name.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
		
		return row;
	}
	
	private TableRow createAddTableRow(boolean solo, int textId, OnClickListener listener)
	{
		// add 'add component' row
		TableRow row = new TableRow(this);
		row.setOnClickListener(listener);
		// style
		TableStyler.styleTableRow(row, solo ? TableRowLocation.Solo: TableRowLocation.Last);
		// add label
		TextView addLabel = new TextView(this);
		addLabel.setText(textId);
		// style
		TableStyler.styleTableRowTextView(this, addLabel, false, true, true, 1);
		// add to row
		row.addView(addLabel);
		
		return row;
	}
	
	private void showDeleteWarning()
	{
		// create alert dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(R.string.rig_delete_warning);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle(R.string.delete_confirmation);
		builder.setPositiveButton(R.string.yes_button, deleteConfirmListener);
		builder.setNegativeButton(R.string.no_button, null);
		AlertDialog dialog = builder.create();
		// show dialog
		dialog.show();
	}
	
	private void updateNotes(String notes)
	{
		// update component
		rig.setNotes(notes);
		
		// update ui
		TextView notesField = (TextView)findViewById(R.id.RigNotesField);
		notesField.setText(rig.getNotes());
	}
	
	private void updateComponent(boolean isDelete, String name, String serialNumber, String notes)
	{
		// update reminder and UI
		if (currentEditedComponent == null)
		{
			// add
			RigComponent component = new RigComponent();
			component.setName(name);
			component.setSerialNumber(serialNumber);
			component.setNotes(notes);
			rig.getComponents().add(component);
		}
		else if (isDelete)
		{
			// delete
			rig.getComponents().remove(currentEditedComponent);
		}
		else
		{
			// update
			currentEditedComponent.setName(name);
			currentEditedComponent.setSerialNumber(serialNumber);
			currentEditedComponent.setNotes(notes);
		}
		
		// update UI
		initComponentsUI();
	}
	
	private void updateReminder(boolean isDelete, String name, int interval, TimeUnit intervalUnit, Date lastCompletedDate)
	{
		// update reminder and UI
		if (currentEditedReminder == null)
		{
			// add reminder
			RigReminder reminder = new RigReminder();
			reminder.setName(name);
			reminder.setInterval(interval);
			reminder.setIntervalUnit(intervalUnit);
			reminder.setLastCompletedDate(lastCompletedDate);
			rig.getReminders().add(reminder);
		}
		else if (isDelete)
		{
			// delete
			rig.getReminders().remove(currentEditedReminder);
		}
		else
		{
			// update
			currentEditedReminder.setName(name);
			currentEditedReminder.setInterval(interval);
			currentEditedReminder.setIntervalUnit(intervalUnit);
			currentEditedReminder.setLastCompletedDate(lastCompletedDate);
		}
		
		// update UI
		initRemindersUI();
	}
	
	private void save()
	{
		// set name
		EditText nField = (EditText)findViewById(R.id.RigNameField);
		rig.setName(nField.getText().toString());
		
		// set primary
		CheckBox pField = (CheckBox)findViewById(R.id.RigPrimaryField);
		rig.setPrimary(pField.isChecked());
		
		// set archived
		CheckBox aField = (CheckBox)findViewById(R.id.RigArchivedField);
		rig.setArchived(aField.isChecked());
		
		// save
		if (isEdit)
		{
			repository.updateRig(rig);
		}
		else
		{
			repository.addRig(rig);
		}
		
		// update rig reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		finish();
	}
	
	private void delete()
	{
		// delete aircraft
		repository.deleteRig(rig);

		// update rig reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		finish();
	}
	
	@Override
	public void onBackPressed()
	{
		save();
		super.onBackPressed();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		
		cancelMenu = menu.add(R.string.cancel_button);
		cancelMenu.setIcon(R.drawable.ic_menu_revert);
		
		saveMenu = menu.add(R.string.save_button);
		saveMenu.setIcon(R.drawable.ic_menu_save);
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		if (item == saveMenu)
		{
        	save();
    		return true;
		}
		else if (item == cancelMenu)
		{
			finish();
			return true;
		}
		else
		{
			return super.onOptionsItemSelected(item);
		}
	}
}
